package cn.agrael.struts.plugin.ejb3;

import static cn.agrael.struts.plugin.ejb3.StrutsEJBPluginConstant.EAR_FILE_BASE_NAME;
import static cn.agrael.struts.plugin.ejb3.StrutsEJBPluginConstant.ENC_PATH;
import static cn.agrael.struts.plugin.ejb3.StrutsEJBPluginConstant.JNDI_PATH_DELIMITER;

import javax.annotation.Resource;
import javax.ejb.EJB;
import javax.ejb.Remote;
import javax.naming.Context;
import javax.naming.NamingException;

/**
 * GlassFish2.x版本 应用服务器的实现。
 * 
 * @author <a href="mailto:agraellee@gmail.com">Agrael·Lee</a>
 * 
 */
public class GlassFish2ApplicationServer extends AbstractApplicationServer {

	protected Object globalLookup(StringBuilder jndiNameBuilder, InjectAnnotationWrapper injectAnnotationWrapper, Class<?> clazz,
			Context context) throws NamingException, Exception {
		Class<?> remoteInterfaceClass = findBusinessInterface(clazz);
		if (remoteInterfaceClass == null) {
			jndiNameBuilder.append(EAR_FILE_BASE_NAME);
			jndiNameBuilder.append(JNDI_PATH_DELIMITER);
			jndiNameBuilder.append((String) null);
			throw new NamingException();
		}
		jndiNameBuilder.append(EAR_FILE_BASE_NAME);
		jndiNameBuilder.append(JNDI_PATH_DELIMITER);
		jndiNameBuilder.append(remoteInterfaceClass.getName());
		return context.lookup(jndiNameBuilder.toString());
	}

	/**
	 * 查找一个类上的业务接口。
	 * 
	 * @param clazz 需要查找业务接口的类的 Class 对象。
	 * @return 如果存在返回第一个业务接口，如果不存在返回 null。
	 */
	protected Class<?> findBusinessInterface(Class<?> clazz) {
		Class<?> remoteInterfaceClass = null;
		if (clazz.isInterface()) {
			remoteInterfaceClass = clazz;
		} else {
			Class<?>[] interfaces = clazz.getInterfaces();
			for (Class<?> interfaceClass : interfaces) {
				// 找到的第一个远程接口作为需要的参数
				if (interfaceClass.isAnnotationPresent(Remote.class)) {
					remoteInterfaceClass = interfaceClass;
					break;
				}
			}
		}
		return remoteInterfaceClass;
	}

	protected void buildEJBBeanNameJndiPath(Class<?> clazz, StringBuilder jndiNameBuilder, Class<?> ejbType, EJB ejb) {
		jndiNameBuilder.append(EAR_FILE_BASE_NAME);
		jndiNameBuilder.append(JNDI_PATH_DELIMITER);
		jndiNameBuilder.append(ejb.beanName());
		jndiNameBuilder.append("#");
		if (Object.class != ejb.beanInterface()) {
			// 使用了 beanInterface 属性则从 beanInterface 中提取本地/远程接口
			Class<?> interfaceClass = ejb.beanInterface();
			jndiNameBuilder.append(interfaceClass.getName());
		} else {
			// 找寻类注解上的本地/远程注解
			Class<?> remoteInterfaceClass = findBusinessInterface(clazz);
			;
			if (remoteInterfaceClass == null) {
				// 移除 #
				jndiNameBuilder.delete(jndiNameBuilder.length() - 1, jndiNameBuilder.length());
			} else {
				// 用接口的完全类名
				jndiNameBuilder.append(remoteInterfaceClass.getName());
			}
		}
	}

	protected void buildEJBMappedNameJndiPath(Class<?> clazz, StringBuilder jndiNameBuilder, Class<?> ejbType, EJB ejb) {
		jndiNameBuilder.append(ejb.mappedName());
	}

	protected void buildEJBNameJndiPath(Class<?> clazz, StringBuilder jndiNameBuilder, Class<?> ejbType, EJB ejb) {
		jndiNameBuilder.append(ENC_PATH);
		jndiNameBuilder.append(ejb.name());
	}

	protected void buildResourceMappedNameJndiPath(Class<?> clazz, StringBuilder jndiNameBuilder, Class<?> resourceType, Resource resource) {
		jndiNameBuilder.append(resource.mappedName());
	}

	protected void buildResourceNameJndiPath(Class<?> clazz, StringBuilder jndiNameBuilder, Class<?> resourceType, Resource resource) {
		jndiNameBuilder.append(ENC_PATH);
		jndiNameBuilder.append(resource.name());
	}

}